// 
// Copyright 2010 Classpath Pty Ltd <opensource@classpath.com.au>
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// 

**
** This class provides a MySql specific implementation of the `Adapter` class.
**
class MySqlAdapter : GenericAdapter {

    **
    ** Creates a new `MySqlAdapter`.
    **
    new make() {
        sqlTypes[SerialType#] = "INT"
    }

    **
    ** Generates the SQL for a column's complete definition for use in a 'CREATE TABLE' or 'ALTER TABLE' statement.
    **
    override Str createColumnSql(CreatedColumn column, Bool includeAdd := false) {
        Pod.of(this).log.debug("${typeof}.createColumnSql(${column}, ${includeAdd}) - start")
        buf := StrBuf()
        if (column.type is SerialType) {
            Pod.of(this).log.debug("MySql doesn't support SERIAL - I'm replacing your column type with 'INT AUTO_INCREMENT'")
            if (includeAdd) {
                buf.join("ADD COLUMN")
            }
            buf.join(column.name)
            buf.join("INT AUTO_INCREMENT")
            column.modifications.find { it is CommentColumnOption } ?.with { 
                sql := commentColumnOptionSql(it)
                if (!sql.isEmpty) {
                    buf.join(sql)
                }
            }
            column.modifications.find { it is DefaultValueColumnOption } ?.with {
                sql := defaultValueColumnOptionSql(it)
                if (!sql.isEmpty) {
                    buf.join(sql)
                }
            }
            column.modifications.find { it is NotNullColumnOption } ?.with {
                sql := notNullColumnOptionSql(it)
                if (!sql.isEmpty) {
                    buf.join(sql)
                }
            }
            column.modifications.find { it is PrimaryKeyColumnOption } ?.with {
                sql := primaryKeyColumnOptionSql(it)
                if (!sql.isEmpty) {
                    buf.join(sql)
                }
            }
            column.modifications.find { it is ReferencesColumnOption } ?.with {
                sql := referencesColumnOptionSql(it)
                if (!sql.isEmpty) {
                    buf.join(sql)
                }
            }
            column.modifications.find { it is UniqueColumnOption } ?.with {
                sql := uniqueColumnOptionSql(it)
                if (!sql.isEmpty) {
                    buf.join(sql)
                }
            }
        }
        else {
            buf.join(super.createColumnSql(column, includeAdd))
        }
        Pod.of(this).log.debug("${typeof}.createColumnSql(${column}, ${includeAdd}) - end - returning ${buf.toStr}")
        return buf.toStr
    }

    **
    ** Overrides the generic handling of adding a 'CHECK' constraint to not use the 'CONSTRAINT ~NAME~' prefix.
    **
    override Str checkTableOptionSql(CheckTableOption option) {
        Pod.of(this).log.debug("${typeof}.checkTableOptionSql(${option}) - start")
        buf := StrBuf()
        buf.join("CHECK (${option.check})")
        Pod.of(this).log.debug("${typeof}.checkTableOptionSql(${option}) - end - returning ${buf.toStr}")
        return buf.toStr
    }

    **
    ** Generates an 'CHECK' option based on the supplied column option
    **
    override Str checkColumnOptionSql(CheckColumnOption option) {
        Pod.of(this).log.debug("${typeof}.checkColumnOptionSql(${option}) - start")
        Pod.of(this).log.warn("MySql doesn't support CHECK on columns (you can still put it on the table) - ignoring")
        Pod.of(this).log.debug("${typeof}.checkColumnOptionSql(${option}) - end - returning ${Str.defVal}")
        return Str.defVal
    }

    **
    ** Generates a 'DROP PRIMARY KEY' statement for inclusion as part of a 'CREATE TABLE' or 'ALTER TABLE' statement.
    **
    override Str dropPrimaryKeyTableOptionSql(DroppedPrimaryKeyTableOption option) {
        Pod.of(this).log.debug("${typeof}.dropPrimaryKeyTableOptionSql(${option}) - start")
        buf := StrBuf()
        buf.join("DROP PRIMARY KEY")
        Pod.of(this).log.debug("${typeof}.dropPrimaryKeyTableOptionSql(${option}) - end - returning ${buf.toStr}")
        return buf.toStr
    }

}
